# coding: utf-8
from enum import Enum
from pathlib import Path
from typing import Union

from PySide6.QtGui import QColor
from PySide6.QtWidgets import QWidget
from qfluentwidgets import StyleSheetBase, Theme, isDarkTheme
from qfluentwidgets.common.style_sheet import QssTemplate, styleSheetManager, StyleSheetFile, updateStyleSheet

from .config import el_config


class ElThemeColor(Enum):
    PRIMARY = "ThemeColorPrimary"
    DARK_1 = "ThemeColorDark1"
    DARK_2 = "ThemeColorDark2"
    DARK_3 = "ThemeColorDark3"
    LIGHT_1 = "ThemeColorLight1"
    LIGHT_2 = "ThemeColorLight2"
    LIGHT_3 = "ThemeColorLight3"

    def name(self):
        return self.color().name()

    def color(self):
        color = el_config.get(el_config._cfg.themeColor)  # type:QColor

        # transform color into hsv space
        h, s, v, _ = color.getHsvF()

        if isDarkTheme():
            s *= 0.84
            v = 1
            if self == self.DARK_1:
                v *= 0.9
            elif self == self.DARK_2:
                s *= 0.977
                v *= 0.82
            elif self == self.DARK_3:
                s *= 0.95
                v *= 0.7
            elif self == self.LIGHT_1:
                s *= 0.92
            elif self == self.LIGHT_2:
                s *= 0.78
            elif self == self.LIGHT_3:
                s *= 0.65
        else:
            if self == self.DARK_1:
                v *= 0.75
            elif self == self.DARK_2:
                s *= 1.05
                v *= 0.5
            elif self == self.DARK_3:
                s *= 1.1
                v *= 0.4
            elif self == self.LIGHT_1:
                v *= 1.05
            elif self == self.LIGHT_2:
                s *= 0.75
                v *= 1.05
            elif self == self.LIGHT_3:
                s *= 0.65
                v *= 1.05

        return QColor.fromHsvF(h, min(s, 1), min(v, 1))


def applyThemeColor(qss: str):
    template = QssTemplate(qss)
    mappings = {c.value: c.name() for c in ElThemeColor._member_map_.values()}
    return template.safe_substitute(mappings)


def getStyleSheet(source: Union[str, StyleSheetBase], theme=Theme.AUTO):
    """ get style sheet

    Parameters
    ----------
    source: str | StyleSheetBase
        qss source, it could be:
          * `str`: qss file path
          * `StyleSheetBase`: style sheet instance

    theme: Theme
        the theme of style sheet
    """
    if isinstance(source, str):
        source = StyleSheetFile(source)

    return applyThemeColor(source.content(theme))


def setStyleSheet(widget: QWidget, source: Union[str, StyleSheetBase], theme=Theme.AUTO, register=True):
    """ set style sheet to widget """
    if register:
        styleSheetManager.register(source, widget)

    widget.setStyleSheet(getStyleSheet(source, theme))


class ElStyleSheet(StyleSheetBase, Enum):
    BUTTON = 'button'
    LINE_EDIT = 'lineedit'
    RICH_TEXT_EDIT = 'richtextedit'

    def path(self, theme=Theme.AUTO):
        theme = el_config.theme if theme == Theme.AUTO else theme
        return f":/element/qss/{theme.value.lower()}/{self.value}.css"

    def apply(self, widget: QWidget, theme=Theme.AUTO):
        """ apply style sheet to widget """
        setStyleSheet(widget, self, theme)


def themeColor():
    """ get theme color """
    return ElThemeColor.PRIMARY.color()


def setThemeColor(color, save=False, lazy=False):
    """ set theme color

    Parameters
    ----------
    color: QColor | Qt.GlobalColor | str
        theme color

    save: bool
        whether to save to change to config file

    lazy: bool
        whether to update the style sheet lazily
    """
    color = QColor(color)
    el_config.set(el_config.themeColor, color, save=save)
    updateStyleSheet(lazy)
